package com.heima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.admin.mapper.AdChannelMapper;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.exception.CustException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.feigns.wemedia.WemediaFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    @Autowired
    WemediaFeign wemediaFeign;
    @Autowired
    ArticleFeign articleFeign;
    @Autowired
    GreenImageScan imageScan;
    @Autowired
    GreenTextScan textScan;
    @Value("file.oss.web-site")
    private String webSite;
    @Autowired
    AdSensitiveMapper adSensitiveMapper;
    @Autowired
    AdChannelMapper adChannelMapper;
    /**
     * 自媒体文章审核
     *
     * @param wmNewsId
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void autoScanByMediaNewsId(Integer wmNewsId) {
        //参数判空
        if (wmNewsId==null){
            log.error("文章id为空");
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
            return;
        }

        //远程调用获取文章,并做非空判断
        WmNews wmNews = wemediaFeign.findById(wmNewsId);
        if (wmNews==null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
            log.error("审核的自媒体文章不存在，自媒体的id:{}",wmNewsId);
            return;
        }

        /**
         * 判断文章状态 status
         *  0 草稿
         * 1 提交（待审核）    解析图片内容和正文并提交自动审核
         * 2 审核失败
         * 3 人工审核
         * 4 人工审核通过   当推送时间小于等于系统时间时    直接保存文章并返回
         * 8 审核通过（待发布）  当推送时间小于等于系统时间时
         *  9 已发布
         */
        if (wmNews.getStatus().equals(WmNews.Status.ADMIN_SUCCESS.getCode())
                &&wmNews.getPublishTime().getTime() <= System.currentTimeMillis()){//4通过
            saveAppArticle(wmNews);
            return;
        }

        if (wmNews.getStatus().equals(WmNews.Status.SUCCESS.getCode())
                && wmNews.getPublishTime().getTime()<=System.currentTimeMillis()){//8通过
            saveAppArticle(wmNews);
            return;
        }

        if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())){//1 待审核
            Map<String, Object> contentAndImagesResult = handleTextAndImages(wmNews);//抽取文章中文字与所有图片
            //自定义敏感词审核  文字内容
            boolean isSensitiveScan = handleSensitive((String) contentAndImagesResult.get("content"), wmNews);
            if (!isSensitiveScan) return;
            //通过阿里云审核文章  文字内容
            boolean isTextScan = handleTextScan((String) contentAndImagesResult.get("content"), wmNews);
            if (!isTextScan)
                return;
            //通过阿里云审核文章  图片内容
            boolean isImageScan=handleImageScan((List)contentAndImagesResult.get("image"),wmNews);
            if (!isImageScan)
                return;

            //发布时间大于当前时间，  且审核通过，   则状态改为8
            if (wmNews.getPublishTime().getTime()>System.currentTimeMillis()) {
                updateWmNews(wmNews, (short) 8, "文章审核通过待发布");
                return;
            }

            //5 审核通过，保存文章相关信息（三张表）， 修改文章的状态=9 已发布
            saveAppArticle(wmNews);

            //TODO 6 ES同步索引库
        }

    }

    /**
     * 自管理敏感词审核   工具类，从数据库查询敏感词
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleSensitive(String content, WmNews wmNews) {
        boolean flag=true;

        List<String> sensitives = adSensitiveMapper.findAllSensitive();
        SensitiveWordUtil.initMap(sensitives);
        Map<String, Integer> map = SensitiveWordUtil.matchWords(content);

        if (map.size()>0){
            flag=false;
            updateWmNews(wmNews,(short)2,"文章含有敏感词"+map);
        }
        return flag;
    }

    /**
     * 阿里云审核图片内容 ==>阿里云,block不通过,review需人工审核，审核过程异常需人工审核
     * @param imageList
     * @param wmNews
     * @return
     */
    private boolean handleImageScan(List<String> imageList, WmNews wmNews) {
        boolean flag=true;
        //无图则不需要审核
        if (imageList==null || imageList.size()==0){
            return flag;
        }
        //有图时调用阿里云工具类审核图片
        try {
            imageList=imageList.stream().distinct().collect(Collectors.toList());//图片去重
            Map map = imageScan.imageUrlScan(imageList);
            if (map.get("suggestion").equals("block")){
                flag=false;
                updateWmNews(wmNews, (short) 2,"图片含敏感信息，审核不通过");
            }
            if (map.get("suggestion").equals("block")){
                flag=false;
                updateWmNews(wmNews, (short) 3,"图片从阿里云转人工审核");
            }
        } catch (Exception e) {
            e.printStackTrace();
            flag=false;
            updateWmNews(wmNews, (short) 3,"阿里云审核异常,转人工审核");
        }
        return flag;
    }

    /**
     * 审核文章内容 ==>阿里云,block不通过,review需人工审核，审核过程异常需人工审核
     * @param content
     * @param wmNews
     * @return
     */
    private boolean handleTextScan(String content, WmNews wmNews) {
        boolean flag=true;
        try {
            Map map = textScan.greeTextScan(content);
            if (map.get("suggestion").equals("block")){
                flag=false;
                updateWmNews(wmNews, (short)2, "文章包含敏感信息,审核不通过");
            }
            if (map.get("suggestion").equals("review")){
                flag=false;
                updateWmNews(wmNews,(short)3, "文本中内容需人工审核");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文章内容阿里云审核失败，转入人工审核, e：{}", e);
            flag=false;
            updateWmNews(wmNews, (short) 3, "文章内容阿里云审核失败,转入需要人工审核");
        }
        return flag;
    }

    /**
     * 更新文章内容
     * @param wmNews
     * @param status
     * @param msg
     */
    private void updateWmNews(WmNews wmNews, short status, String msg) {
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        ResponseResult result = wemediaFeign.updateWmNews(wmNews);
        if (!result.getCode().equals(0)){
            CustException.cust(AppHttpCodeEnum.WEMEDIA_UPDATE_ERROR);
        }
    }

    /**
     * 抽取文章内容中的文本和图片
     * @param wmNews
     * @return
     */
    private Map<String,Object> handleTextAndImages(WmNews wmNews) {
        String content = wmNews.getContent();
        if (StringUtils.isNotBlank(content) && content.length()<10000){
            List<Map> contentList = JSON.parseArray(content, Map.class);
            StringBuilder contents = new StringBuilder();
            List<String> imageList=new ArrayList<>();
            for (Map<String,String> map : contentList) {
                if (map.get("type").equals("text")){
                    contents.append(map.get("value"));
                    contents.append("-qweqe-");
                }
                if (map.get("type").equals("image")){
                    imageList.add( map.get("value"));
                    contents.append("-qweqe-");
                }
            }
            if (StringUtils.isNotBlank(wmNews.getImages())){
                String[] images = wmNews.getImages().split(",");
                for (String image : images) {
                    imageList.add(webSite+image);
                }
            }

            Map<String,Object> resultMap=new HashMap<>();
            resultMap.put("content",contents.toString());
            resultMap.put("images",imageList);

            return  resultMap;
        }

        return new HashMap<>();
    }

    /**
     * 保存APP端文章相关数据
     * @param wmNews
     */
    private void saveAppArticle(WmNews wmNews) {
        ResponseResult result=saveArticle(wmNews);
        if (result.getCode()!=0){//返回状态码不是0，success时
            CustException.cust(AppHttpCodeEnum.ARTICE_SAVE_ERROR);
        }
        //文章保存完毕,wmnews中状态改为发布,拿到文章返回的id
        Object data = result.getData();
        wmNews.setArticleId((Long) data);
        updateWmNews(wmNews, (short) 9, "审核通过文章已发布");
    }

    /**
     * 远程调用article 保存文章信息，更新 article、article_content、article_config表
     * @param wmNews
     * @return
     */
    private ResponseResult saveArticle(WmNews wmNews) {
        ArticleDto articleDto=new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        //文章id存在时执行修改操作，注意bean拷贝的字段问题
        if (wmNews.getArticleId()!=null){
            articleDto.setId(wmNews.getArticleId());
        }
        //设置作者信息,作者id先不设置，尽量减少远程调用次数
        WmUser wmUser=wemediaFeign.findWmUserById(wmNews.getUserId());
        if (wmUser!=null){
            articleDto.setAuthorName(wmUser.getName());
        }
        //设置频道数据
        AdChannel channel = adChannelMapper.selectById(wmNews.getChannelId());
        if (channel!=null){
            articleDto.setChannelId(channel.getId());
            articleDto.setChannelName(channel.getName());
        }

        articleDto.setLayout(wmNews.getType().intValue());
        articleDto.setFlag((byte) 0);
        articleDto.setCreatedTime(new Date());
        articleDto.setOrigin(true);

        return articleFeign.saveArticle(articleDto);
    }
}
